package org.styx.seata.tcc.storage.tcc.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.styx.common.utils.ResultHolder;
import org.styx.seata.tcc.storage.domain.Storage;
import org.styx.seata.tcc.storage.mapper.StorageMapper;
import org.styx.seata.tcc.storage.tcc.StorageTccAction;

/**
 * @date 2021/10/8
 * @auther uranus
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class StorageTccActionImpl implements StorageTccAction {
    private final StorageMapper storageMapper;

    @Transactional
    @Override
    public boolean prepareDecreaseStorage(BusinessActionContext context,
                                          Long productId, Integer count) {
        log.info("减少库存第一阶段，开始执行冻结操作");
        //先查询库存，看是否可以冻结
        Storage storage=
                storageMapper.selectOne(new LambdaQueryWrapper<Storage>().eq(Storage::getProductId,productId));
        if(storage.getResidue()<count){
            throw new RuntimeException("库存量不足，无法完成冻结操作");
        }
        //冻结操作
        storageMapper.updateFrozen(storage.getProductId(),
                storage.getResidue()-count,storage.getFrozen()+count);
        //添加标记
        ResultHolder.setResult(StorageTccAction.class,context.getXid(),"p");
        log.info("减少库存第一阶段，执行冻结操作成功");
        return true;
    }
    @Transactional
    @Override
    public boolean commit(BusinessActionContext context) {
        if(ResultHolder.getResult(StorageTccAction.class,context.getXid())==null){
            return true;
        }
        log.info("减少库存第二阶段，开始执行提交操作");
        Long productId=
                Long.parseLong(context.getActionContext("productId").toString());
        int count=
                Integer.parseInt(context.getActionContext("count").toString());
        storageMapper.updateFrozenToUsed(productId,count);
        log.info("减少库存第二队阶段，执行提交操作完毕");
        ResultHolder.removeResult(StorageTccAction.class,context.getXid());
        return false;
    }
    @Transactional
    @Override
    public boolean rollback(BusinessActionContext context) {
        //防止重复回滚
        if(ResultHolder.getResult(StorageTccAction.class,context.getXid())==null){
            return true;
        }
        log.info("减少库存第二阶段，执行回滚操作");
        Long productId=
                Long.parseLong(context.getActionContext("productId").toString());
        int count=
                Integer.parseInt(context.getActionContext("count").toString());
        log.info("减少库存第二队阶段，执行回滚操作完毕");
        ResultHolder.removeResult(StorageTccAction.class,context.getXid());
        return true;
    }
}
